"""
报告生成模块
根据数据分析结果生成详细报告
"""
import pandas as pd
import json
import logging
from typing import Dict, List, Any, Optional
from datetime import datetime
import os
from jinja2 import Template
import base64

logger = logging.getLogger(__name__)

class ReportGenerator:
    """报告生成器"""
    
    def __init__(self, analysis_results: Dict[str, Any]):
        """
        初始化报告生成器
        
        Args:
            analysis_results: 数据分析结果
        """
        self.analysis_results = analysis_results
        self.report_data = {}
        
    def prepare_report_data(self) -> Dict[str, Any]:
        """
        准备报告数据
        
        Returns:
            格式化的报告数据
        """
        logger.info("准备报告数据...")
        
        # 基础信息
        self.report_data['metadata'] = {
            'report_title': '数据分析报告',
            'generation_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'analysis_timestamp': self.analysis_results.get('analysis_timestamp', ''),
            'data_summary': self.analysis_results.get('data_summary', {})
        }
        
        # 数据概览
        if 'basic_statistics' in self.analysis_results.get('analysis_results', {}):
            basic_stats = self.analysis_results['analysis_results']['basic_statistics']
            self.report_data['data_overview'] = {
                'total_records': basic_stats.get('total_records', 0),
                'total_features': basic_stats.get('column_count', 0),
                'data_types': basic_stats.get('data_types', {}),
                'missing_values_summary': self._summarize_missing_values(basic_stats.get('missing_values', {}))
            }
        
        # 标注结果分析
        if 'label_analysis' in self.analysis_results.get('analysis_results', {}):
            label_analysis = self.analysis_results['analysis_results']['label_analysis']
            self.report_data['labeling_summary'] = {
                'total_labeled': label_analysis.get('total_labeled', 0),
                'confidence_summary': self._summarize_confidence(label_analysis.get('confidence_analysis', {})),
                'category_summary': self._summarize_categories(label_analysis.get('category_analysis', {})),
                'sentiment_summary': self._summarize_sentiment(label_analysis.get('sentiment_analysis', {})),
                'quality_summary': self._summarize_quality(label_analysis.get('quality_analysis', {}))
            }
        
        # 相关性分析
        if 'correlation_analysis' in self.analysis_results.get('analysis_results', {}):
            corr_analysis = self.analysis_results['analysis_results']['correlation_analysis']
            self.report_data['correlation_insights'] = self._summarize_correlations(corr_analysis)
        
        # 趋势分析
        if 'trend_analysis' in self.analysis_results.get('analysis_results', {}):
            trend_analysis = self.analysis_results['analysis_results']['trend_analysis']
            self.report_data['trend_insights'] = self._summarize_trends(trend_analysis)
        
        # 异常值检测
        if 'outlier_detection' in self.analysis_results.get('analysis_results', {}):
            outlier_analysis = self.analysis_results['analysis_results']['outlier_detection']
            self.report_data['outlier_insights'] = self._summarize_outliers(outlier_analysis)
        
        # 可视化
        self.report_data['visualizations'] = self.analysis_results.get('visualizations', {})
        
        logger.info("报告数据准备完成")
        return self.report_data
    
    def _summarize_missing_values(self, missing_values: Dict[str, int]) -> Dict[str, Any]:
        """总结缺失值情况"""
        if not missing_values:
            return {'has_missing': False}
        
        total_missing = sum(missing_values.values())
        missing_columns = [col for col, count in missing_values.items() if count > 0]
        
        return {
            'has_missing': total_missing > 0,
            'total_missing': total_missing,
            'missing_columns': missing_columns,
            'most_missing_column': max(missing_values, key=missing_values.get) if missing_values else None
        }
    
    def _summarize_confidence(self, confidence_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结置信度分析"""
        if not confidence_analysis:
            return {'has_confidence': False}
        
        return {
            'has_confidence': True,
            'mean_confidence': confidence_analysis.get('mean', 0),
            'confidence_level': self._get_confidence_level(confidence_analysis.get('mean', 0)),
            'distribution': confidence_analysis.get('distribution', {})
        }
    
    def _get_confidence_level(self, mean_confidence: float) -> str:
        """获取置信度等级"""
        if mean_confidence >= 0.8:
            return '高'
        elif mean_confidence >= 0.6:
            return '中'
        else:
            return '低'
    
    def _summarize_categories(self, category_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结类别分析"""
        if not category_analysis:
            return {'has_categories': False}
        
        return {
            'has_categories': True,
            'total_categories': category_analysis.get('total_categories', 0),
            'top_category': category_analysis.get('most_common', [('未知', 0)])[0][0],
            'distribution': category_analysis.get('distribution', {})
        }
    
    def _summarize_sentiment(self, sentiment_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结情感分析"""
        if not sentiment_analysis:
            return {'has_sentiment': False}
        
        return {
            'has_sentiment': True,
            'dominant_sentiment': sentiment_analysis.get('most_common', [('未知', 0)])[0][0],
            'distribution': sentiment_analysis.get('distribution', {})
        }
    
    def _summarize_quality(self, quality_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结质量分析"""
        if not quality_analysis:
            return {'has_quality': False}
        
        mean_score = quality_analysis.get('mean_score', 0)
        return {
            'has_quality': True,
            'mean_quality_score': mean_score,
            'quality_level': self._get_quality_level(mean_score),
            'distribution': quality_analysis.get('score_distribution', {})
        }
    
    def _get_quality_level(self, mean_score: float) -> str:
        """获取质量等级"""
        if mean_score >= 8:
            return '优秀'
        elif mean_score >= 6:
            return '良好'
        elif mean_score >= 4:
            return '一般'
        else:
            return '较差'
    
    def _summarize_correlations(self, correlation_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结相关性分析"""
        if not correlation_analysis:
            return {'has_correlations': False}
        
        strong_correlations = correlation_analysis.get('strong_correlations', [])
        return {
            'has_correlations': len(strong_correlations) > 0,
            'strong_correlation_count': len(strong_correlations),
            'highly_correlated_pairs': correlation_analysis.get('highly_correlated_pairs', 0),
            'top_correlations': strong_correlations[:5]  # 前5个强相关
        }
    
    def _summarize_trends(self, trend_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结趋势分析"""
        if not trend_analysis:
            return {'has_trends': False}
        
        trends = []
        for col, analysis in trend_analysis.items():
            trends.append({
                'column': col,
                'direction': analysis.get('trend_direction', 'unknown'),
                'slope': analysis.get('trend_slope', 0)
            })
        
        return {
            'has_trends': len(trends) > 0,
            'trend_count': len(trends),
            'trends': trends
        }
    
    def _summarize_outliers(self, outlier_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """总结异常值分析"""
        if not outlier_analysis:
            return {'has_outliers': False}
        
        return {
            'has_outliers': outlier_analysis.get('total_outlier_columns', 0) > 0,
            'outlier_column_count': outlier_analysis.get('total_outlier_columns', 0),
            'outlier_columns': outlier_analysis.get('outlier_columns', [])
        }
    
    def generate_executive_summary(self) -> str:
        """
        生成执行摘要
        
        Returns:
            执行摘要文本
        """
        if not self.report_data:
            self.prepare_report_data()
        
        summary_parts = []
        
        # 数据概览
        data_overview = self.report_data.get('data_overview', {})
        summary_parts.append(f"本次分析共处理了 {data_overview.get('total_records', 0)} 条记录，包含 {data_overview.get('total_features', 0)} 个特征。")
        
        # 标注结果
        labeling_summary = self.report_data.get('labeling_summary', {})
        if labeling_summary.get('total_labeled', 0) > 0:
            confidence_summary = labeling_summary.get('confidence_summary', {})
            summary_parts.append(f"共标注了 {labeling_summary['total_labeled']} 条数据，平均置信度为 {confidence_summary.get('confidence_level', '未知')}。")
            
            category_summary = labeling_summary.get('category_summary', {})
            if category_summary.get('has_categories'):
                summary_parts.append(f"数据主要分为 {category_summary.get('total_categories', 0)} 个类别，其中 '{category_summary.get('top_category', '未知')}' 类别占比最高。")
        
        # 质量评估
        quality_summary = labeling_summary.get('quality_summary', {})
        if quality_summary.get('has_quality'):
            summary_parts.append(f"数据整体质量评估为 '{quality_summary.get('quality_level', '未知')}'，平均得分 {quality_summary.get('mean_quality_score', 0):.1f}。")
        
        # 相关性洞察
        correlation_insights = self.report_data.get('correlation_insights', {})
        if correlation_insights.get('has_correlations'):
            summary_parts.append(f"发现 {correlation_insights.get('strong_correlation_count', 0)} 组强相关特征，其中 {correlation_insights.get('highly_correlated_pairs', 0)} 组为高度相关。")
        
        # 异常值
        outlier_insights = self.report_data.get('outlier_insights', {})
        if outlier_insights.get('has_outliers'):
            summary_parts.append(f"检测到 {outlier_insights.get('outlier_column_count', 0)} 个特征存在异常值，建议进一步调查。")
        
        return ' '.join(summary_parts)
    
    def generate_recommendations(self) -> List[str]:
        """
        生成建议
        
        Returns:
            建议列表
        """
        recommendations = []
        
        # 基于数据质量的建议
        data_overview = self.report_data.get('data_overview', {})
        missing_summary = data_overview.get('missing_values_summary', {})
        if missing_summary.get('has_missing'):
            recommendations.append("建议处理缺失值，特别是关注缺失值较多的特征。")
        
        # 基于置信度的建议
        labeling_summary = self.report_data.get('labeling_summary', {})
        confidence_summary = labeling_summary.get('confidence_summary', {})
        if confidence_summary.get('has_confidence'):
            if confidence_summary.get('mean_confidence', 0) < 0.7:
                recommendations.append("标注置信度偏低，建议重新检查标注规则或增加训练数据。")
            elif confidence_summary.get('mean_confidence', 0) > 0.9:
                recommendations.append("标注置信度很高，可以考虑扩大标注规模或增加更复杂的标注任务。")
        
        # 基于类别分布的建议
        category_summary = labeling_summary.get('category_summary', {})
        if category_summary.get('has_categories'):
            if category_summary.get('total_categories', 0) > 10:
                recommendations.append("类别数量较多，建议考虑合并相似类别或采用层次化分类。")
        
        # 基于相关性的建议
        correlation_insights = self.report_data.get('correlation_insights', {})
        if correlation_insights.get('highly_correlated_pairs', 0) > 0:
            recommendations.append("存在高度相关的特征，建议进行特征选择以避免多重共线性。")
        
        # 基于异常值的建议
        outlier_insights = self.report_data.get('outlier_insights', {})
        if outlier_insights.get('has_outliers'):
            recommendations.append("检测到异常值，建议进行数据清洗或异常值处理。")
        
        # 默认建议
        if not recommendations:
            recommendations.append("数据质量整体良好，可以继续进行深入分析。")
        
        return recommendations
    
    def generate_html_report(self, output_path: str = 'data_analysis_report.html') -> str:
        """
        生成HTML格式报告
        
        Args:
            output_path: 输出路径
            
        Returns:
            生成的报告路径
        """
        logger.info("生成HTML报告...")
        
        if not self.report_data:
            self.prepare_report_data()
        
        # HTML模板
        html_template = """
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>{{ metadata.report_title }}</title>
            <style>
                body {
                    font-family: 'Microsoft YaHei', Arial, sans-serif;
                    line-height: 1.6;
                    margin: 0;
                    padding: 20px;
                    background-color: #f5f5f5;
                }
                .container {
                    max-width: 1200px;
                    margin: 0 auto;
                    background: white;
                    padding: 30px;
                    border-radius: 10px;
                    box-shadow: 0 0 10px rgba(0,0,0,0.1);
                }
                h1 {
                    color: #2c3e50;
                    border-bottom: 3px solid #3498db;
                    padding-bottom: 10px;
                }
                h2 {
                    color: #34495e;
                    margin-top: 30px;
                }
                .summary {
                    background-color: #ecf0f1;
                    padding: 20px;
                    border-radius: 5px;
                    margin: 20px 0;
                }
                .metrics {
                    display: grid;
                    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
                    gap: 20px;
                    margin: 20px 0;
                }
                .metric-card {
                    background: #f8f9fa;
                    padding: 20px;
                    border-radius: 5px;
                    border-left: 4px solid #3498db;
                }
                .metric-value {
                    font-size: 24px;
                    font-weight: bold;
                    color: #2c3e50;
                }
                .metric-label {
                    color: #7f8c8d;
                    font-size: 14px;
                }
                .recommendations {
                    background-color: #d5edda;
                    border: 1px solid #c3e6cb;
                    padding: 20px;
                    border-radius: 5px;
                    margin: 20px 0;
                }
                .recommendations h3 {
                    color: #155724;
                    margin-top: 0;
                }
                .recommendations ul {
                    color: #155724;
                }
                .visualization {
                    text-align: center;
                    margin: 20px 0;
                }
                .visualization img {
                    max-width: 100%;
                    height: auto;
                    border: 1px solid #ddd;
                    border-radius: 5px;
                }
                .footer {
                    text-align: center;
                    margin-top: 40px;
                    color: #7f8c8d;
                    font-size: 12px;
                }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>{{ metadata.report_title }}</h1>
                <p><strong>报告生成时间：</strong>{{ metadata.generation_time }}</p>
                
                <div class="summary">
                    <h2>执行摘要</h2>
                    <p>{{ executive_summary }}</p>
                </div>
                
                <h2>数据概览</h2>
                <div class="metrics">
                    <div class="metric-card">
                        <div class="metric-value">{{ data_overview.total_records }}</div>
                        <div class="metric-label">总记录数</div>
                    </div>
                    <div class="metric-card">
                        <div class="metric-value">{{ data_overview.total_features }}</div>
                        <div class="metric-label">总特征数</div>
                    </div>
                    {% if labeling_summary.total_labeled > 0 %}
                    <div class="metric-card">
                        <div class="metric-value">{{ labeling_summary.total_labeled }}</div>
                        <div class="metric-label">已标注数据</div>
                    </div>
                    {% endif %}
                    {% if labeling_summary.confidence_summary.has_confidence %}
                    <div class="metric-card">
                        <div class="metric-value">{{ labeling_summary.confidence_summary.confidence_level }}</div>
                        <div class="metric-label">置信度等级</div>
                    </div>
                    {% endif %}
                </div>
                
                {% if labeling_summary.category_summary.has_categories %}
                <h2>类别分析</h2>
                <p>数据共分为 {{ labeling_summary.category_summary.total_categories }} 个类别，主要类别为 "{{ labeling_summary.category_summary.top_category }}"。</p>
                {% endif %}
                
                {% if labeling_summary.quality_summary.has_quality %}
                <h2>质量评估</h2>
                <p>数据整体质量评估为 "{{ labeling_summary.quality_summary.quality_level }}"，平均得分 {{ "%.1f"|format(labeling_summary.quality_summary.mean_quality_score) }}。</p>
                {% endif %}
                
                {% if correlation_insights.has_correlations %}
                <h2>相关性分析</h2>
                <p>发现 {{ correlation_insights.strong_correlation_count }} 组强相关特征，其中 {{ correlation_insights.highly_correlated_pairs }} 组为高度相关。</p>
                {% endif %}
                
                {% if outlier_insights.has_outliers %}
                <h2>异常值检测</h2>
                <p>检测到 {{ outlier_insights.outlier_column_count }} 个特征存在异常值：{{ outlier_insights.outlier_columns | join(', ') }}。</p>
                {% endif %}
                
                {% if visualizations %}
                <h2>可视化图表</h2>
                {% for name, path in visualizations.items() %}
                <div class="visualization">
                    <h3>{{ name }}</h3>
                    <img src="{{ path }}" alt="{{ name }}">
                </div>
                {% endfor %}
                {% endif %}
                
                <div class="recommendations">
                    <h3>建议</h3>
                    <ul>
                    {% for recommendation in recommendations %}
                        <li>{{ recommendation }}</li>
                    {% endfor %}
                    </ul>
                </div>
                
                <div class="footer">
                    <p>本报告由数据分析系统自动生成</p>
                </div>
            </div>
        </body>
        </html>
        """
        
        # 准备模板数据
        template_data = self.report_data.copy()
        template_data['executive_summary'] = self.generate_executive_summary()
        template_data['recommendations'] = self.generate_recommendations()
        
        # 渲染模板
        template = Template(html_template)
        html_content = template.render(**template_data)
        
        # 保存文件
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(html_content)
        
        logger.info(f"HTML报告已生成：{output_path}")
        
        return output_path
    
    def generate_json_report(self, output_path: str = 'data_analysis_report.json') -> str:
        """
        生成JSON格式报告
        
        Args:
            output_path: 输出路径
            
        Returns:
            生成的报告路径
        """
        logger.info("生成JSON报告...")
        
        if not self.report_data:
            self.prepare_report_data()
        
        # 准备完整的报告数据
        report_json = {
            'metadata': self.report_data.get('metadata', {}),
            'executive_summary': self.generate_executive_summary(),
            'data_overview': self.report_data.get('data_overview', {}),
            'labeling_summary': self.report_data.get('labeling_summary', {}),
            'correlation_insights': self.report_data.get('correlation_insights', {}),
            'trend_insights': self.report_data.get('trend_insights', {}),
            'outlier_insights': self.report_data.get('outlier_insights', {}),
            'visualizations': self.report_data.get('visualizations', {}),
            'recommendations': self.generate_recommendations(),
            'raw_analysis_results': self.analysis_results
        }
        
        # 保存JSON文件
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(report_json, f, ensure_ascii=False, indent=2, default=str)
        
        logger.info(f"JSON报告已生成：{output_path}")
        
        return output_path

# 使用示例
if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(level=logging.INFO)
    
    # 示例分析结果
    sample_analysis_results = {
        'analysis_timestamp': '2024-01-01T10:00:00',
        'data_summary': {
            'total_records': 1000,
            'total_features': 10
        },
        'analysis_results': {
            'basic_statistics': {
                'total_records': 1000,
                'column_count': 10,
                'missing_values': {'column1': 50, 'column2': 0}
            },
            'label_analysis': {
                'total_labeled': 1000,
                'confidence_analysis': {
                    'mean': 0.85,
                    'distribution': {'high_confidence': 800, 'medium_confidence': 150, 'low_confidence': 50}
                },
                'category_analysis': {
                    'total_categories': 3,
                    'most_common': [('正面', 500), ('负面', 300), ('中性', 200)]
                }
            }
        }
    }
    
    # 创建报告生成器
    generator = ReportGenerator(sample_analysis_results)
    
    # 生成HTML报告
    html_path = generator.generate_html_report()
    
    # 生成JSON报告
    json_path = generator.generate_json_report()
    
    print(f"报告已生成：\nHTML: {html_path}\nJSON: {json_path}") 